<?php

namespace app\service;

use app\tool\SingletonTrait;
use app\model\OriginalPlanNodeDetailModel;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;

class OriginalPlanNodeService
{
    use SingletonTrait;

    public function __construct()
    {
    }

    /**
     * 生成异常任务必要查询条件的
     * @param $query
     * @param $projectId
     * @param $stepCategoryIds
     * @return void
     */
    protected function generateAbnormalTaskMustFilter(&$query, $projectId, $stepCategoryIds)
    {
        $query->where('opn.node_type', '=', OriginalPlanNodeDetailModel::NODE_TYPE_DELIVERY)  //查询交付节点
        ->where('opn.delivery_status', 'in', [OriginalPlanNodeDetailModel::DELIVERY_STATUS_UNDELIVERED, OriginalPlanNodeDetailModel::DELIVERY_STATUS_DEFAULT])    //查询状态：未交付 和 进行中的
        ->where('opn.step_category_id', 'in', $stepCategoryIds)
            ->where('opn.project_id', '=', $projectId);
    }

    /**
     * 从saas服务获取，根据实体分类工序分类列表ids
     * @param $entityModuleCode
     * @return array|mixed
     */
    protected function getStepCategoryListByEntityFromSaas($entityModuleCode)
    {
        $res = teamones_request('teamones-saas', 'step_category/get_step_category_list_by_entity', [
            'param' => [
                'entity_module_code' => $entityModuleCode
            ]
        ]);

        if (empty($res['data'])) {
            return [];
        }

        return $res['data'];
    }

    /**
     * 获取指定状态
     * @param $name
     * @return int|mixed
     */
    protected function getTaskStatusByNameFromSaas($name)
    {
        $res = teamones_request('teamones-saas', 'status/get_default_status', [
            'name' => $name
        ]);

        if (empty($res['data'])) {
            return '';
        }

        return $res['data']['id'];
    }

    /**
     * 获取历史存在异常的集数列表，附带异常实体数据统计
     * @param string $entityModuleCode
     * @param int $projectId
     * @param array $timeRange
     * @return array
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getHistoryAbnormalEpisodeList(string $entityModuleCode, int $projectId, array $timeRange)
    {
        // 通过实体模块编码获取包含的工序分类ids
        $stepCategoryIds = $this->getStepCategoryListByEntityFromSaas($entityModuleCode);
        if (empty($stepCategoryIds)) {
            return [];
        }

        // 降低统计损耗，可以先判断是否存在一条任务数据
        $existAbnormalTaskQuery = OriginalPlanNodeDetailModel::field('id')->alias('opn');
        // 必要条件
        $this->generateAbnormalTaskMustFilter($existAbnormalTaskQuery, $projectId, $stepCategoryIds);
        $existAbnormalTask = $existAbnormalTaskQuery->where('opn.original_delivery_time', 'between', [$timeRange[0], trim_time_range_end($timeRange[1], (get_today_end_time() - 86400))])->find();

        // [{"name":"EP001", "count": 2}]
        $episodeList = [];
        if (!empty($existAbnormalTask)) {
            // 获取已经关闭的任务状态列表，历史数据要用 status/get_default_status
            $closedStatusId = $this->getTaskStatusByNameFromSaas('default_deprecate_status');
            $courtAbnormalTaskQuery = OriginalPlanNodeDetailModel::alias('opn')
                ->join("task t", "t.id = opn.task_id", "left")
                ->field('opn.initial_episode_code as name,count(distinct opn.entity_id) as count');

            // 必要条件
            $this->generateAbnormalTaskMustFilter($courtAbnormalTaskQuery, $projectId, $stepCategoryIds);
            $episodeList = $courtAbnormalTaskQuery->where('opn.original_delivery_time', 'BETWEEN', [$timeRange[0], trim_time_range_end($timeRange[1], (get_today_end_time() - 86400))])
                ->whereRaw("get_json_string(t.`json`, '$.task_status') <> $closedStatusId")
                ->group('opn.initial_episode_code')
                ->select();;

            if (empty($episodeList)) {
                return [];
            }
        }

        return $episodeList;
    }
}
